package org.ranch.dao.impl;

import java.util.List;

import org.hibernate.SessionFactory;
import org.springframework.beans.factory.annotation.Autowired;

import com.googlecode.genericdao.dao.hibernate.GenericDAOImpl;
import com.googlecode.genericdao.search.Search;
import org.ranch.dao.BaseDAO;
import org.ranch.model.BaseData;
import org.ranch.model.RecordStatus;

/**
 * Abstract Base class for all Data Access interface Implementations and
 * abstracts<br/>
 * </br/>
 * 
 * This class requires the hibernate {@link SessionFactory} <br/>
 * <br/>
 * 
 * This class also extends the {@link GenericDAOImpl} which is a hibernate
 * specific implementation of the {@link GenericDAO} interface. This allows our
 * implementing classes to use generics when providing CRUD operations
 * 
 * @param <T>
 */
public abstract class BaseDAOImpl<T> extends GenericDAOImpl<T, String>
		implements BaseDAO<T> {

    /*
     * (non-Javadoc)
     * 
     * @see
     * com.trg.dao.hibernate.HibernateBaseDAO#setSessionFactory(org.hibernate
     * .SessionFactory)
     */
    @Autowired
    @Override
    public void setSessionFactory(SessionFactory sessionFactory) {
	super.setSessionFactory(sessionFactory);
    }

    /*
     * (non-Javadoc)
     * 
     * @see
     * org.pearcorp.awmu.server.dao.BaseDAO#searchByPropertyEqual(java.lang.
     * String, java.lang.Object)
     */
    @Override
    public List<T> searchByPropertyEqual(String property, Object value) {
	Search search = new Search();
	search.addFilterEqual(property, value);
	search.addFilterEqual("recordStatus", RecordStatus.ACTIVE);
	return search(search);
    }

    /*
     * (non-Javadoc)
     * 
     * @see
     * org.pearcorp.awmu.server.dao.BaseDAO#searchUniqueByPropertyEqual(java
     * .lang.String, java.lang.Object)
     */
    @SuppressWarnings("unchecked")
    @Override
    public T searchUniqueByPropertyEqual(String property, Object value) {
	Search search = new Search();
	search.addFilterEqual(property, value);
	search.addFilterEqual("recordStatus", RecordStatus.ACTIVE);
	return (T) searchUnique(search);
    }

    /*
     * (non-Javadoc)
     * 
     * @see com.pearcorp.commons.dao.BaseDAO#delete(java.lang.Object)
     */
    @Override
    public void delete(T entity) {
	if (entity != null) {
	    if (entity instanceof BaseData) {
		((BaseData) entity).setRecordStatus(RecordStatus.DELETED);
		super.save(entity);
	    }
	}
    }

    /*
     * (non-Javadoc)
     * 
     * @see com.pearcorp.commons.dao.BaseDAO#update(java.lang.Object)
     */
    @Override
    public void update(T entity) {
	super.save(entity);
    }

    /*
     * (non-Javadoc)
     * 
     * @see com.pearcorp.commons.dao.BaseDAO#add(java.lang.Object)
     */
    @Override
    public void add(T entity) {
	super.save(entity);
    }

    /*
     * (non-Javadoc)
     * 
     * @see org.mak.cis.mohr.dao.BaseDAO#searchByPropertyEqual(java.lang.String,
     * java.lang.Object, org.mak.cis.mohr.model.RecordStatus)
     */
    @Override
    public List<T> searchByPropertyEqual(String property, Object value,
			RecordStatus recordStatus) {
	Search search = new Search();
	search.addFilterEqual(property, value);
	search.addFilterEqual("recordStatus", recordStatus);
	return search(search);
    }

    /*
     * (non-Javadoc)
     * 
     * @see
     * org.mak.cis.mohr.dao.BaseDAO#searchUniqueByPropertyEqual(java.lang.String
     * , java.lang.Object, org.mak.cis.mohr.model.RecordStatus)
     */
    @SuppressWarnings("unchecked")
    @Override
    public T searchUniqueByPropertyEqual(String property, Object value,
			RecordStatus recordStatus) {
	Search search = new Search();
	search.addFilterEqual(property, value);
	search.addFilterEqual("recordStatus", recordStatus);
	return (T) searchUnique(search);
    }

    /*
     * (non-Javadoc)
     * 
     * @see
     * org.mak.cis.mohr.dao.BaseDAO#searchByRecordStatus(org.mak.cis.mohr.model
     * .RecordStatus)
     */
    @Override
    public List<T> searchByRecordStatus(RecordStatus recordStatus) {
	Search search = new Search();
	search.addFilterEqual("recordStatus", recordStatus);
	return search(search);
    }
}
